package com.yunchang.springboot.scheduled.mwsfinance;

import com.yunchang.springboot.base.BaseService;
import com.yunchang.springboot.mapper.caravan.CaravanMskuDataMapper;
import com.yunchang.springboot.mapper.finance.FinanceCaravanDebitCreditRelationMapper;
import com.yunchang.springboot.mapper.mwsfinance.FFbaShipmentSalesMapper;
import com.yunchang.springboot.mapper.mwsfinance.FInventoryDailyMapper;
import com.yunchang.springboot.mapper.mwsreport.MwsCustomerShipmentSalesMapper;
import com.yunchang.springboot.mapper.mwsreport.MwsDailyInventoryHistoryMapper;
import com.yunchang.springboot.mapper.mwsreport.MwsFbaCustomerReturnsMapper;
import com.yunchang.springboot.models.mwsfinance.FFbaCustomerReturn;
import com.yunchang.springboot.models.mwsreportbean.MwsFbaCustomerReturns;
import com.yunchang.springboot.utils.DateUtil;
import com.yunchang.springboot.utils.StringUtil;
import com.yunchang.springboot.utils.UUIDUtil;
import com.yunchang.springboot.utils.mwsutils.GetCountryByCurrency;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * 亚马逊退货
 */
@Component
@Configuration
@Service
@Slf4j
@EnableScheduling
public class FFbaCustomerReturnScheduled extends BaseService {


    /**
     * 出入库明细
     */
    @Autowired
    FInventoryDetailsScheduled fInventoryDetailsScheduled;

    /**
     * 贷方科目
     */
    private static final String CREDIT_SUBJECT_ID = "140201";

    static Integer LIMIT_VALUE = 10000;

    static final List<String> EU_COUNTRY_LIST = Arrays.asList("DE", "FR", "IT", "UK", "ES");

    static final String US = "US";

    static final String CA = "CA";

    static final String MX = "MX";

    static final String JP = "JP";

    static final String EU = "EU";

    static String DOCUMENTS_ID = "THRKD";

    /**
     * 亚马逊退货原始数据
     */
    private MwsFbaCustomerReturnsMapper mwsFbaCustomerReturnsMapper;

    @Autowired
    public void setMwsFbaCustomerReturnsMapper(MwsFbaCustomerReturnsMapper mwsFbaCustomerReturnsMapper) {
        this.mwsFbaCustomerReturnsMapper = mwsFbaCustomerReturnsMapper;
    }

    /**
     * 已完成订单财务数据
     */
    private FFbaShipmentSalesMapper fFbaShipmentSalesMapper;

    @Autowired
    public void setFFbaShipmentSalesMapper(FFbaShipmentSalesMapper fFbaShipmentSalesMapper) {
        this.fFbaShipmentSalesMapper = fFbaShipmentSalesMapper;
    }

    /**
     * 库存数据
     */
    private FInventoryDailyMapper fInventoryDailyMapper;

    @Autowired
    public void setFInventoryDailyMapper(FInventoryDailyMapper fInventoryDailyMapper) {
        this.fInventoryDailyMapper = fInventoryDailyMapper;
    }

    /**
     * 亚马逊每日库存记录原始数据
     */
    private MwsDailyInventoryHistoryMapper mwsDailyInventoryHistoryMapper;

    @Autowired
    public void setMwsDailyInventoryHistoryMapper(MwsDailyInventoryHistoryMapper mwsDailyInventoryHistoryMapper){
        this.mwsDailyInventoryHistoryMapper = mwsDailyInventoryHistoryMapper;
    }

    /**
     * 已完成订单原始数据
     */
    private MwsCustomerShipmentSalesMapper mwsCustomerShipmentSalesMapper;

    @Autowired
    public void setMwsCustomerShipmentSalesMapper(MwsCustomerShipmentSalesMapper mwsCustomerShipmentSalesMapper) {
        this.mwsCustomerShipmentSalesMapper = mwsCustomerShipmentSalesMapper;
    }

    /**
     * 获取stock_sku
     */
    private CaravanMskuDataMapper caravanMskuDataMapper;

    @Autowired
    public void setCaravanMskuDataMapper(CaravanMskuDataMapper caravanMskuDataMapper) {
        this.caravanMskuDataMapper = caravanMskuDataMapper;
    }

    /**
     * 获取costUnit
     */
    private FinanceCaravanDebitCreditRelationMapper financeCaravanDebitCreditRelationMapper;

    @Autowired
    public void setFinanceCaravanDebitCreditRelationMapper(FinanceCaravanDebitCreditRelationMapper financeCaravanDebitCreditRelationMapper) {
        this.financeCaravanDebitCreditRelationMapper = financeCaravanDebitCreditRelationMapper;
    }


    public void getFFbaCustomerReturn(String date) throws ParseException {
        List<MwsFbaCustomerReturns> mwsFbaCustomerReturnsList = mwsFbaCustomerReturnsMapper.selectByFinanceStatus(1, null, date);
        Integer mwsFbaCustomerReturnsListSize = mwsFbaCustomerReturnsList.size();
        int forNum = 1;
        log.info("亚马逊退货原始数据的数量为：" + mwsFbaCustomerReturnsListSize);
        if (mwsFbaCustomerReturnsListSize > LIMIT_VALUE) {
            forNum += mwsFbaCustomerReturnsListSize / LIMIT_VALUE;
            for (; forNum > 0; forNum--) {
                log.info("亚马逊退货生成财务数据剩余次数：" + forNum);
                mwsFbaCustomerReturnsList = mwsFbaCustomerReturnsMapper.selectByFinanceStatus(1, LIMIT_VALUE, date);
                mwsFbaCustomerReturnsDispose(mwsFbaCustomerReturnsList);
            }
        } else {
            mwsFbaCustomerReturnsDispose(mwsFbaCustomerReturnsList);
        }
    }

    public void mwsFbaCustomerReturnsDispose(List<MwsFbaCustomerReturns> mwsFbaCustomerReturnsList) throws ParseException {
        if (null != mwsFbaCustomerReturnsList && !mwsFbaCustomerReturnsList.isEmpty()) {
            List<Object> fFbaCustomerReturnInsertList = new ArrayList<>();
            for (MwsFbaCustomerReturns mwsFbaCustomerReturns : mwsFbaCustomerReturnsList) {
                FFbaCustomerReturn fFbaCustomerReturn = new FFbaCustomerReturn();
                fFbaCustomerReturn.setIsAdjustManauly(1);
                fFbaCustomerReturn.setApprovalStatus(1);
                fFbaCustomerReturn.setIsInventoryDetails(1);
                fFbaCustomerReturn.setDocumentsId(DOCUMENTS_ID + UUIDUtil.getUUID());
                fFbaCustomerReturn.setSellerId(mwsFbaCustomerReturns.getSellerId());
                String country = null;
                String sellerId = mwsFbaCustomerReturns.getSellerId();
                String orderId = mwsFbaCustomerReturns.getOrderId();
                String area = mwsFbaCustomerReturns.getArea();
                String returnDate = mwsFbaCustomerReturns.getReturnDate();
                String sku = mwsFbaCustomerReturns.getSku();
                String fulfillmentCenterId = mwsFbaCustomerReturns.getFulfillmentCenterId();
                String countryShip = getCountryShip(fulfillmentCenterId,area);
                if(StringUtil.isBlank(countryShip)){
                    log.info("亚马逊退货，获取countryShip为空，fulfillmentCenterId: "+fulfillmentCenterId+" area: "+area);
                }
                fFbaCustomerReturn.setCountryShip(countryShip);
                Map<String,String> countryMap = getCountry(sellerId,orderId,area,sku,returnDate);
                if(null != countryMap && !countryMap.isEmpty()){
                    if(countryMap.containsKey("country")){
                        country = countryMap.get("country");
                    }
                    if (countryMap.containsKey("country2")){
                        fFbaCustomerReturn.setCountryStatus(2);
                        country = countryMap.get("country2");
                    }
                    if(countryMap.containsKey("country3")){
                        fFbaCustomerReturn.setCountryStatus(3);
                        country = countryMap.get("country3");
                    }
                }
                fFbaCustomerReturn.setCountry(country);
                fFbaCustomerReturn.setReturnDate(returnDate);
                fFbaCustomerReturn.setOrderId(mwsFbaCustomerReturns.getOrderId());
                fFbaCustomerReturn.setSku(mwsFbaCustomerReturns.getSku());
                fFbaCustomerReturn.setAsin(mwsFbaCustomerReturns.getAsin());
                fFbaCustomerReturn.setFnsku(mwsFbaCustomerReturns.getFnsku());
                String detailedDisposition = mwsFbaCustomerReturns.getDetailedDisposition();
                fFbaCustomerReturn.setDetailedDisposition(mwsFbaCustomerReturns.getDetailedDisposition());
                Integer commodityStatus = getCommodityStatusByDetailedDisposition(detailedDisposition);
                if (3 == commodityStatus) {
                    fFbaCustomerReturn.setIsAdjustManauly(2);
                    fFbaCustomerReturn.setCommodityStatus(0);
                } else {
                    fFbaCustomerReturn.setCommodityStatus(commodityStatus);
                }
                Integer quantity = mwsFbaCustomerReturns.getQuantity();
                fFbaCustomerReturn.setQuantity(quantity);
                Double costUnit = null;
                Map<String,Double> costUnitMap = getCostUnit(mwsFbaCustomerReturns.getSellerId(), mwsFbaCustomerReturns.getOrderId(), mwsFbaCustomerReturns.getSku(), countryShip);
                if(null != costUnitMap && !costUnitMap.isEmpty()){
                    if(costUnitMap.containsKey("costUnit")){
                        costUnit = costUnitMap.get("costUnit");
                    }
                    if(costUnitMap.containsKey("costUnit2")){
                        costUnit = costUnitMap.get("costUnit2");
                        fFbaCustomerReturn.setCostUnitStatus(2);
                    }
                    if(costUnitMap.containsKey("costUnit3")){
                        costUnit = costUnitMap.get("costUnit3");
                        fFbaCustomerReturn.setCostUnitStatus(3);
                    }
                }
                if (null != costUnit) {
                    fFbaCustomerReturn.setCostUnit(costUnit);
                    fFbaCustomerReturn.setAmount(new BigDecimal(quantity * costUnit).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                }
                fFbaCustomerReturn.setCurrency("RMB");
                fFbaCustomerReturn.setDebitSubjectId(getDebitSubjectIdByCommodityStatus(commodityStatus));
                fFbaCustomerReturn.setCreditSubjectId(CREDIT_SUBJECT_ID);
                fFbaCustomerReturn.setCreateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fFbaCustomerReturn.setUpdateTime(DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
                fFbaCustomerReturnInsertList.add(fFbaCustomerReturn);
                mwsFbaCustomerReturns.setFinanceStatus(2);
            }
            try {
                baseInsertList(fFbaCustomerReturnInsertList);
                mwsFbaCustomerReturnsMapper.updateFinanceStatusByMwsFbaCustomerReturnsList(mwsFbaCustomerReturnsList);
                log.info("亚马逊退货财务数据已生成");
            } catch (Exception e) {
                log.error("插入数据时出现错误，亚马逊退货" + e);
                throw new RuntimeException("插入数据时出现错误，亚马逊退货");
            }
        } else {
            log.info("未查询到对应的亚马逊退货数据列表，时间为" + DateUtil.getTodayDate("yyyy-MM-dd HH:mm:ss"));
        }
    }

    /**
     * 根据sellerId和orderId在所有订单中查找salesChannel（marketPlaceName）,再根据salesChannel获取country
     *
     * @param sellerId
     * @param orderId
     * @return
     */
    public Map<String,String> getCountry(String sellerId, String orderId,String area,String sku,String returnDate) throws ParseException {
        String currency = mwsCustomerShipmentSalesMapper.selectCurrencyBySellerIdAndAmazonOrderId(sellerId, orderId);
        if (!StringUtils.isEmpty(currency)) {
            return new HashMap<String,String>(1){{
                put("country", GetCountryByCurrency.getCountryByCurrency(currency));
            }};
        } else  if (area.equals(JP)) {
             return new HashMap<String,String>(1){{
                put("country",JP);
            }};
        }else if (EU_COUNTRY_LIST.contains(area)) {
            return new HashMap<String,String>(1){{
                put("country",EU);
            }};
        }else {
            List<String> countryList = mwsDailyInventoryHistoryMapper.selectCountryBySellerIdAndSkuAndReturnDate(sellerId,sku,returnDate.substring(0,10));
            if(null != countryList && !countryList.isEmpty() && countryList.size() == 1){
                    return new HashMap<String,String>(1){{
                        put("country",countryList.get(0));
                    }};
            }else {
                // 获取returnDate前一天的country
                List<String> countryListByBefore = mwsDailyInventoryHistoryMapper.selectCountryBySellerIdAndSkuAndReturnDate(sellerId,sku,DateUtil.dateToFutureDate(returnDate, -1).substring(0,10));
                if(null != countryListByBefore && !countryListByBefore.isEmpty()){
                    if(countryListByBefore.size() == 1){
                        return new HashMap<String,String>(1){{
                            put("country",countryListByBefore.get(0));
                        }};
                    }
                }else {
                    if(orderId.startsWith("1")){
                        return new HashMap<String,String>(1){{
                            put("country","US");
                        }};
                    }
                    if(orderId.startsWith("7")){
                        return new HashMap<String,String>(1){{
                            put("country2","CA");
                        }};
                    }
                    return new HashMap<String,String>(1){{
                        put("country3","US");
                    }};
                }
            }
        }
        log.info("获取区域名失败,亚马逊退货。sellerId: "+sellerId +" orderId: "+orderId + " area: "+area +" sku: "+ sku +" returnDate: "+returnDate);
        return  new HashMap<String,String>(1){{
            put("country3","US");
        }};
    }

    /**
     * 根据 returnDate 获取 WarehouseDate
     *
     * @param returnDate
     * @return
     */
    public String getWarehouseDate(String returnDate) throws ParseException {
        if (StringUtils.isEmpty(returnDate)) {
            return "";
        }
        String warehouseDate;
        String standardReturnDate = returnDate.substring(0, 10) + " 08:00:00";
        if (1 == DateUtil.compateTime(returnDate, standardReturnDate) || 0 == DateUtil.compateTime(returnDate, standardReturnDate)) {
            warehouseDate = returnDate.substring(0, 10);
        } else {
            warehouseDate = DateUtil.dateToFutureDate(returnDate.substring(0, 10), -1);
        }
        return warehouseDate;
    }

    /**
     * 根据 DetailedDisposition 返回对应的 CommodityStatus
     *
     * @return
     */
    public Integer getCommodityStatusByDetailedDisposition(String detailedDisposition) {
        detailedDisposition = detailedDisposition.toUpperCase();
        String sellAble = "SELLABLE";
        Integer commodityStatus;
        List<String> commodityStatusTwo = Arrays.asList("DAMAGED", "CARRIER DAMAGED", "CARRIER_DAMAGED","CARRIERDAMAGED");
        List<String> commodityStatusZero = Arrays.asList("CUSTOMER DAMAGED", "CUSTOMER_DAMAGED", "DEFECTIVE", "EXPIRED","CUSTOMERDAMAGED");
        if (sellAble.equals(detailedDisposition)) {
            commodityStatus = 1;
        } else if (commodityStatusTwo.contains(detailedDisposition)) {
            commodityStatus = 2;
        } else if (commodityStatusZero.contains(detailedDisposition)) {
            commodityStatus = 0;
        } else {
            commodityStatus = 3;
        }
        return commodityStatus;
    }

    /**
     * 根据sellerId 和 orderId 和 sku 获取 CostUnit ，暂时时间未确定
     *
     * @param sellerId
     * @param orderId
     * @param sku
     * @return
     */
    public Map<String, Double> getCostUnit(String sellerId, String orderId, String sku, String country) {
        List<String> warehouseList = Arrays.asList("140603", "140605");
        List<String> warehouseListByReturn = Arrays.asList("140201");
        if (!StringUtils.isEmpty(sellerId) && !StringUtils.isEmpty(orderId) && !StringUtils.isEmpty(sku)) {
            Double amount = fFbaShipmentSalesMapper.selectSumAmountBySellerIdAndOrderIdAndSku(sellerId, orderId, sku);
            Integer quantity = fFbaShipmentSalesMapper.selectSumQuantityBySellerIdAndOrderIdAndSku(sellerId, orderId, sku);
            if (null != amount && null != quantity && amount != 0.0 && quantity != 0) {
                return new HashMap<String, Double>(1) {{
                    put("costUnit", new BigDecimal(amount / quantity).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                }};
            }
            if (!StringUtils.isEmpty(country)) {
                Map<String, Object> amountAndQuantityMapByReturn = fInventoryDailyMapper.selectSumAmountAndSumQuantityBySellerIdAndCountryAndSkuAndWarehouseListNoDate(sellerId, country, sku, warehouseListByReturn);
                if (null != amountAndQuantityMapByReturn && !amountAndQuantityMapByReturn.isEmpty()) {
                    if (null != amountAndQuantityMapByReturn.get("amount") && null != amountAndQuantityMapByReturn.get("quantity")) {
                        Double amountByInventory = new Double(amountAndQuantityMapByReturn.get("amount").toString());
                        Integer quantityByInventory = new Integer(amountAndQuantityMapByReturn.get("quantity").toString());
                        if (null != amountByInventory && null != quantityByInventory && amountByInventory != 0.0 && quantityByInventory != 0) {
                            return new HashMap<String, Double>(1) {{
                                put("costUnit", new BigDecimal(amountByInventory / quantityByInventory).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                            }};
                        }
                    }
                }
                Map<String, Object> amountAndQuantityMap = fInventoryDailyMapper.selectSumAmountAndSumQuantityBySellerIdAndCountryAndSkuAndWarehouseList(sellerId, country, sku, warehouseList);
                if (null != amountAndQuantityMap && !amountAndQuantityMap.isEmpty()) {
                    if (null != amountAndQuantityMap.get("amount") && null != amountAndQuantityMap.get("quantity")) {
                        Double amountByInventory = new Double(amountAndQuantityMap.get("amount").toString());
                        Integer quantityByInventory = new Integer(amountAndQuantityMap.get("quantity").toString());
                        if (null != amountByInventory && null != quantityByInventory && amountByInventory != 0.0 && quantityByInventory != 0) {
                            return new HashMap<String, Double>(1) {{
                                put("costUnit", new BigDecimal(amountByInventory / quantityByInventory).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                            }};
                        }
                    }
                }
            }
            String warehouse = "默认仓库";
            String subjectId = "1406";
            String stockSku = getStockSku(sku);
            Map<String, Object> amountAndSkuNumMap = financeCaravanDebitCreditRelationMapper.selectSumSkuNumAndSumAmountByStockSkuAndWarehouseAndSubjectId(stockSku,warehouse,subjectId);
            if(null != amountAndSkuNumMap && null != amountAndSkuNumMap.get("amount") && null != amountAndSkuNumMap.get("skuNum")){
                Double amountByFinance = new Double(amountAndSkuNumMap.get("amount").toString());
                Integer skuNum = new Integer(amountAndSkuNumMap.get("skuNum").toString());
                if (null != amountByFinance && null != skuNum && amountByFinance != 0 && skuNum != 0) {
                    return new HashMap<String, Double>(1) {{
                        put("costUnit2", new BigDecimal((amountByFinance / skuNum)+15).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
                    }};
                }
            }
        }
        log.info("getCostUnit 获取costUnit使用默认值60，亚马逊退货生成财务数据。sellerId："+sellerId+" country："+country+" sku："+sku);
        // 最后默认返回60
        return new HashMap<String, Double>(1) {{
            put("costUnit3", new BigDecimal(60).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
        }};
    }


    /**
     * 根据sku获取stockSku
     * @param sku
     * @return
     */
    public String getStockSku(String sku){
        if(StringUtils.isEmpty(sku)){
            log.info("根据sku获取stockSku失败，sku为空，盘库生成财务数据");
            return null;
        }
        return  caravanMskuDataMapper.getStockSku(sku);
    }


    /**
     * 根据 commodityStatus 获取对应的借方科目
     *
     * @param commodityStatus
     * @return
     */
    public String getDebitSubjectIdByCommodityStatus(Integer commodityStatus) {
        String debitSubjectId = null;
        switch (commodityStatus) {
            case 0:
                debitSubjectId = "140605";
                break;
            case 1:
                debitSubjectId = "140603";
                break;
            case 2:
                debitSubjectId = "140601";
                break;
        }
        return debitSubjectId;
    }


    /**
     * 获取countryShip
     * @param fulfillmentCenterId
     * @param area
     * @return
     */
    public String getCountryShip(String fulfillmentCenterId,String area){
        String country = null;
        if (area.equals(JP)) {
            return JP;
        }
        if (EU_COUNTRY_LIST.contains(area)) {
            return EU;
        }
        if (!StringUtils.isEmpty(fulfillmentCenterId)) {
            country = mwsDailyInventoryHistoryMapper.getCountryByFulfillmentCenterId(fulfillmentCenterId);
        }
        return country;
    }
}
